﻿#include "HttpClientController.h"
#include <QTimer>
#include <QEventLoop>
#include <QUrlQuery>
HttpClientController::HttpClientController()
{
    pHttpRequest = new QNetworkRequest();
    pHttpManager = new QNetworkAccessManager(this);
}

HttpClientController::~HttpClientController()
{
    if(pHttpRequest != nullptr)
    {
        delete pHttpRequest;
        pHttpRequest = nullptr;
    }
    if(pHttpManager != nullptr)
    {
        delete pHttpManager;
        pHttpManager = nullptr;
    }

}

/**
 * @brief HttpClientController::ValidateHttpResponse 检验Http反馈数据包
 * @param pReply
 * @return
 */
bool HttpClientController::ValidateHttpResponse(QNetworkReply *pReply)
{
    QString responseData;

    QString httpUrl = pReply->url().toString();
    responseData.append(QString::fromUtf8("服务端地址:") + httpUrl + '\n');

    // 取出服务器端的状态响应码
    QVariant statusCode = pHttpReply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
    if (statusCode.isValid())
    {
        QString strStatusCode;
        strStatusCode = strStatusCode.setNum(statusCode.toInt());
        responseData.append(QString::fromUtf8("状态码:") + strStatusCode + '\n');
    }

    // 取出网络连接错误信息
    QNetworkReply::NetworkError err = pHttpReply->error();

    if (err != QNetworkReply::NoError)
    {
        responseData.append(QString::fromUtf8("网络错误:") + pHttpReply->errorString() + '\n');

        emit sig_SendHttpValidateInfo(responseData);

        return false;
    }

    emit sig_SendHttpValidateInfo(responseData);

    return true;
}


/**
 * @brief HttpClientController::GetUrl 构建附加信息的Url （QT5.x支持QUrlQuery类）
 * @param baseUrl
 * @param params
 * @return Url字符串
 */
QUrl HttpClientController::GetUrl(QString baseUrl, QVariantMap params)
{
    QUrl      url;
    QUrlQuery query;

    url.setUrl(baseUrl); // 服务端地址

    if (params.empty())
        return url;

    // 组建附加信息
    for (QVariantMap::iterator it = params.begin(); it != params.end(); it++)
    {
        query.addQueryItem(it.key(), it.value().toString());
    }

    url.setQuery(query); // 附加信息

    return url;
}

/**
 * @brief HttpClientController::GetAsync Http的异步Get操作
 * @param url     服务端地址
 * @param params  查询参数
 * @return 服务端反馈数据模型
 */
QByteArray HttpClientController::GetAsync(QString url, QVariantMap params)
{
    QNetworkRequest request;
    QUrl serverUrl;

    if (params.contains("Authorization")) // 包含新增头部
    {
        serverUrl = url;
        // 设置服务端地址
        request.setRawHeader(QByteArray("Authorization"), QByteArray(params["Authorization"].value<QString>().toLatin1()));
    }
    else // 不包含新增头部
    {
        serverUrl = GetUrl(url, params);
    }
    // 设置服务端地址
    request.setUrl(serverUrl);

    // 向服务器请求数据
    pHttpReply = pHttpManager->get(request);

    // 利用Event机制不堵塞主线程等待服务端的响应，服务端反馈报文后退出Event机制
    QEventLoop eventLoop;
    connect(pHttpManager, SIGNAL(finished(QNetworkReply *)), &eventLoop, SLOT(quit()));
    eventLoop.exec();

    // 是否网络连接错误信息
    if (pHttpReply->error() == QNetworkReply::NoError)
    {
        // 读取二进制数据
        QByteArray responseData = pHttpReply->readAll();
        // 删除该响应
        pHttpReply->deleteLater();

        return responseData;
    }
//    mylog<<pHttpReply->error();
    // 删除该响应
    pHttpReply->deleteLater();
    // 抛出网络错误信息的异常
    //throw pHttpReply->errorString();
    return "";
}

/**
 * @brief HttpClientController::DeleteAsync Http的异步Delete操作
 * @param url     服务端地址
 * @param params  查询参数
 * @return 服务端反馈数据模型
 */
QByteArray HttpClientController::DeleteAsync(QString url, QVariantMap params)
{
    QNetworkRequest  request;

    // 设置服务端地址
    QUrl serverUrl = GetUrl(url, params);
    request.setUrl(serverUrl);

    // 向服务器请求数据
    pHttpReply = pHttpManager->deleteResource(request);

    // 利用Event机制不堵塞主线程等待服务端的响应，服务端反馈报文后退出Event机制
    QEventLoop eventLoop;
    connect(pHttpManager, SIGNAL(finished(QNetworkReply *)), &eventLoop, SLOT(quit()));

    eventLoop.exec();

    // 是否网络连接错误信息
    if (pHttpReply->error() == QNetworkReply::NoError)
    {
        // 读取二进制数据
        QByteArray responseData = pHttpReply->readAll();
        // 删除该响应
        pHttpReply->deleteLater();

        return responseData;

    }

    // 删除该响应
    pHttpReply->deleteLater();
    // 抛出网络错误信息的异常
    throw pHttpReply->errorString();
}

/**
 * @brief HttpClientController::PutAsync Http的异步Put操作
 * @param url     服务端地址
 * @param params  查询参数
 * @param data    提交服务端的数据包
 * @return
 */
QByteArray HttpClientController::PutAsync(QString url, QByteArray jsonData)
{
    QNetworkRequest  request;

    QUrl serverUrl;
    serverUrl.setUrl(url);
    // 设置服务端地址
    request.setUrl(serverUrl);

    // request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); //  设置请求格式为Json
    request.setRawHeader("Content-Type", "application/json");
    // 向服务器发送数据
    pHttpReply = pHttpManager->put(request, jsonData);

    // 利用Event机制不堵塞主线程等待服务端的响应，服务端反馈报文后退出Event机制
    QEventLoop eventLoop;
    connect(pHttpManager, SIGNAL(finished(QNetworkReply *)), &eventLoop, SLOT(quit()));
    eventLoop.exec();

    // 是否网络连接错误信息
    if (pHttpReply->error() == QNetworkReply::NoError)
    {
        // 读取二进制数据
        QByteArray responseData = pHttpReply->readAll();
        // 删除该响应
        pHttpReply->deleteLater();

        return responseData;
    }

    // 删除该响应
    pHttpReply->deleteLater();
    // 抛出网络错误信息的异常
    throw pHttpReply->errorString();
}

/**
 * @brief HttpClientController::PostAsync Http的异步Post操作
 * @param url     服务端地址
 * @param params  查询参数
 * @param data    提交服务端的数据包
 * @return
 */
QByteArray HttpClientController::PostAsync(QString url, QByteArray jsonData)
{
    QNetworkRequest  request;

    QUrl       serverUrl;
    serverUrl.setUrl(url);
    // 设置服务端地址
    request.setUrl(serverUrl);

    request.setRawHeader("Content-Type", "application/json");
    // request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");  //  设置请求格式为Json
    //  向服务器发送数据
    pHttpReply = pHttpManager->post(request, jsonData);

    // 利用Event机制不堵塞主线程等待服务端的响应，服务端反馈报文后退出Event机制
    QEventLoop eventLoop;
    connect(pHttpManager, SIGNAL(finished(QNetworkReply *)), &eventLoop, SLOT(quit()));
    eventLoop.exec();

    // 是否网络连接错误信息
    if (pHttpReply->error() == QNetworkReply::NoError)
    {
        // 读取二进制数据
        QByteArray responseData = pHttpReply->readAll();
        // 删除该响应
        pHttpReply->deleteLater();
        return responseData;
    }

    // 删除该响应
    pHttpReply->deleteLater();
    // 抛出网络错误信息的异常
    throw pHttpReply->errorString();
}
